# Loading Regex library
library(qdapRegex)

Attaching package: ‘qdapRegex’

The following object is masked from ‘package:dplyr’:

    explain

The following object is masked from ‘package:ggplot2’:

    %+%
# Extract tweet text from climate dataset
twt_txt <- climate_twts$text
head(twt_txt)
[1] "I don't think it's too much of an exaggeration to say everyone's fate on the planet probably hinges on the dems winning these 2 Georgia Senate seats the science is clear https://t.co/qmFkKqOwC2 https://t.co/M04ZS22LB0"                                                               
[2] "BOM and CSIRO State of the Climate 2020 shows Australia is experiencing climate change now\nhttps://t.co/HdxntH6ziX"                                                                                                                                                                     
[3] "\"[this] “offensive inquisitiveness” whose goal of humiliating others [is] inherently objectionable... “gossip derived from malicious judgment of others” could only “cast a shadow of worthlessness” over humanity + climate of rage ... inimical to civil peace and social progress.\""
[4] "Trashing Labor on Climate policy,\nHas Michelle looked at the government??\n\nApparently it’s ok to question China on everything but it’s not ok to question thing’s attacks on US democracy.\n\nhttps://t.co/Djschiqc9g"                                                                
[5] "@BigDuke6__ @djmirk @CytometerMan @DPWIMM @realDonaldTrump @ChanelRion @OANN Funny, I thought that was climate change??"                                                                                                                                                                 
[6] "@timinmitcham Expect thousands of climate change refugees to seek asylum!"                                                                                                                                                                                                               
# Remove URLs from the tweet text
twt_txt_url <- rm_twitter_url(twt_txt)

# Replace special characters, punctuation, & numbers with spaces
twt_txt_chrs  <- gsub("[^A-Za-z]"," " , twt_txt_url)

# Loading text mining library
library(tm)
Loading required package: NLP

Attaching package: ‘NLP’

The following object is masked from ‘package:ggplot2’:

    annotate
# Convert text in "twt_gsub" dataset to a text corpus
twt_corpus <- twt_txt_chrs %>% 
                VectorSource() %>% 
                Corpus() 

# Convert the corpus to lowercase
twt_corpus_lwr <- tm_map(twt_corpus, tolower) 
transformation drops documents
# Remove English stop words from the corpus using SMART dictionary and view the corpus
twt_corpus_stpwd <- tm_map(twt_corpus_lwr, removeWords, stopwords("smart"))
transformation drops documents
head(twt_corpus_stpwd$content)
[1] " don         exaggeration     fate   planet  hinges   dems winning    georgia senate seats  science  clear"                                                                                                                      
[2] "bom  csiro state   climate      shows australia  experiencing climate change "                                                                                                                                                   
[3] "     offensive inquisitiveness   goal  humiliating     inherently objectionable     gossip derived  malicious judgment       cast  shadow  worthlessness   humanity   climate  rage     inimical  civil peace  social progress  "
[4] "trashing labor  climate policy   michelle looked   government   apparently     question china         question thing  attacks   democracy "                                                                                      
[5] " bigduke     djmirk  cytometerman  dpwimm  realdonaldtrump  chanelrion  oann funny   thought   climate change  "                                                                                                                 
[6] " timinmitcham expect thousands  climate change refugees  seek asylum "                                                                                                                                                           
# Remove additional spaces from the corpus
twt_corpus_spaces <- tm_map(twt_corpus_stpwd, stripWhitespace)
transformation drops documents
# Loading library for text analysis
library(qdap)
Loading required package: qdapDictionaries
Loading required package: qdapTools
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     

Attaching package: ‘qdapTools’

The following object is masked from ‘package:dplyr’:

    id

Loading required package: RColorBrewer

Attaching package: ‘qdap’

The following objects are masked from ‘package:tm’:

    as.DocumentTermMatrix, as.TermDocumentMatrix

The following object is masked from ‘package:NLP’:

    ngrams

The following object is masked from ‘package:rtweet’:

    %>%

The following object is masked from ‘package:forcats’:

    %>%

The following object is masked from ‘package:stringr’:

    %>%

The following object is masked from ‘package:dplyr’:

    %>%

The following object is masked from ‘package:purrr’:

    %>%

The following object is masked from ‘package:tidyr’:

    %>%

The following object is masked from ‘package:tibble’:

    %>%

The following objects are masked from ‘package:base’:

    Filter, proportions
# Extract term frequencies for top 60 words and view output
termfreq  <-  freq_terms(twt_corpus_spaces, 60)
termfreq
# Create a vector of custom stop words
custom_stopwds <- c("amp", "ve", "don", "lo", "climate", "change")

# Remove custom stop words and create a refined corpus
corp_refined <- tm_map(twt_corpus_spaces, removeWords, custom_stopwds) 
transformation drops documents
# Extract term frequencies for the top 25 words
termfreq_25w <- freq_terms(corp_refined, 25)

# Identify terms with more than 30 counts from the top 25 list
term30 <- subset(termfreq_25w, FREQ > 30)


# Barchart
term30 %>% 
ggplot() +
aes(x = reorder(WORD, -FREQ), y = FREQ) +
        geom_bar(stat = "identity", fill = "blue") + 
        theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Create word cloud with 10 colors and max 30 words
wordcloud(corp_refined, max.words = 30, 
    colors = brewer.pal(10, "Dark2"), 
    scale=c(4,1), random.order = FALSE)
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors


# Load libraries
library(topicmodels)


# Create a document term matrix (DTM) for *climate*
dtm_climate <- DocumentTermMatrix(corp_refined)

# Find the sum of word counts in each document
rowTotals <- apply(dtm_climate, 1, sum)

# Select rows with a row total greater than zero
dtm_climate_new <- dtm_climate[rowTotals > 0, ]

# Create a topic model with 10 topics
topicmodl_10 <- LDA(dtm_climate_new, k = 10)

# Select and view the top 10 terms in the topic model
top_10terms <- terms(topicmodl_10, 10)
top_10terms 
      Topic 1      Topic 2   Topic 3   Topic 4     Topic 5       Topic 6     Topic 7    
 [1,] "trump"      "people"  "action"  "global"    "time"        "global"    "work"     
 [2,] "crisis"     "biden"   "make"    "biden"     "covid"       "biden"     "people"   
 [3,] "biden"      "action"  "global"  "action"    "environment" "energy"    "biden"    
 [4,] "snow"       "science" "science" "oil"       "green"       "years"     "energy"   
 [5,] "action"     "energy"  "biden"   "world"     "snow"        "today"     "policy"   
 [6,] "nov"        "covid"   "time"    "australia" "world"       "emissions" "world"    
 [7,] "oil"        "health"  "live"    "crisis"    "great"       "people"    "political"
 [8,] "years"      "make"    "crisis"  "big"       "planet"      "crisis"    "crisis"   
 [9,] "government" "report"  "years"   "report"    "global"      "science"   "good"     
[10,] "green"      "years"   "good"    "science"   "pandemic"    "trump"     "future"   
      Topic 8      Topic 9   Topic 10   
 [1,] "biden"      "people"  "people"   
 [2,] "trump"      "world"   "world"    
 [3,] "action"     "csiro"   "biden"    
 [4,] "covid"      "global"  "justice"  
 [5,] "future"     "control" "make"     
 [6,] "world"      "time"    "crisis"   
 [7,] "current"    "great"   "current"  
 [8,] "year"       "lost"    "future"   
 [9,] "government" "year"    "emissions"
[10,] "carbon"     "state"   "health"   
library(syuzhet)

Attaching package: ‘syuzhet’

The following object is masked from ‘package:rtweet’:

    get_tokens
# Perform sentiment analysis for tweets on `ClimateCrisis` 
sa.value <- get_nrc_sentiment(climate_twts$text)
`filter_()` is deprecated as of dplyr 0.7.0.
Please use `filter()` instead.
See vignette('programming') for more help
This warning is displayed once every 8 hours.
Call `lifecycle::last_warnings()` to see where this warning was generated.`group_by_()` is deprecated as of dplyr 0.7.0.
Please use `group_by()` instead.
See vignette('programming') for more help
This warning is displayed once every 8 hours.
Call `lifecycle::last_warnings()` to see where this warning was generated.`data_frame()` is deprecated as of tibble 1.1.0.
Please use `tibble()` instead.
This warning is displayed once every 8 hours.
Call `lifecycle::last_warnings()` to see where this warning was generated.
# View the sentiment scores
head(sa.value, 10)
# Calculate sum of sentiment scores
score <- colSums(sa.value[,])

# Convert the sum of scores to a data frame
score_df <- data.frame(score)

# Convert row names into 'sentiment' column and combine with sentiment scores
score_df2 <- cbind(sentiment = row.names(score_df),  
                  score_df, row.names = NULL)
print(score_df2)

# Plot the sentiment scores
ggplot(data = score_df2, aes(x = sentiment, y = score, fill = sentiment)) +
     geom_bar(stat = "identity") +
       theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Compute the in-degree scores from the retweet network
in_degree <- degree(nw_rply, mode = c("in"))

# Sort the in-degree scores in decreasing order
in_degree_sort <- sort(in_degree, decreasing = TRUE)

# View users with the top 10 in-degree scores
in_degree_sort[1:10]
   BorisJohnson    senatemajldr          afneil    KamalaHarris     seanhannity          mcuban 
            179              74              70              63              57              51 
            ozm realDonaldTrump        JoeBiden       zerohedge 
             43              41              30              24 
# Calculate the betweenness scores from the retweet network
Warning messages:
1: In readChar(file, size, TRUE) : truncating string with embedded nuls
2: In readChar(file, size, TRUE) : truncating string with embedded nuls
3: In readChar(file, size, TRUE) : truncating string with embedded nuls
4: In readChar(file, size, TRUE) : truncating string with embedded nuls
betwn_nw <- betweenness(nw_rply, directed = TRUE)

# Sort betweenness scores in decreasing order and round the values
betwn_nw_sort <- betwn_nw %>%
                    sort(decreasing = TRUE) %>%
                    round()

# View users with the top 10 betweenness scores 
betwn_nw_sort[1:10]
   XRebellionUK    bjames280961 RebeccaElisabe3   richardabetts    Climatehope2        erinbiba 
            203             184              68              39              29              21 
 emilyhewertson        hausfath  T0myBarrient0s  JesseLReynolds 
             20              19              18              14 

library(maps)


# Extract geo-coordinates data to append as new columns
cc_coord <- lat_lng(climate_twts)

# Omit rows with missing geo-coordinates in the data frame
cc_geo <- na.omit(cc_coord[,c("lat", "lng")])

# Plot longitude and latitude values of tweets on UK
map(database = "world", region = "UK(?!r)", fill = TRUE, col = "light green")
with(cc_geo, points(lng, lat, pch = 20, cex = 1, col = 'blue'))


# Plot longitude and latitude values of tweets on the world map
map(database = "world", fill = TRUE, col = "light green")
with(cc_geo, points(lng, lat, pch = 20, cex = 1, col = 'blue'))

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3IgbWVzc2FnZT1GQUxTRX0KIyBMb2FkIGxpYnJhcmllcwpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShodHRwdXYpCmxpYnJhcnkocnR3ZWV0KQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGhlcmUpCmxpYnJhcnkocmpzb24pCmBgYAoKYGBge3J9CgpjaW1hdGVfdHd0cyA8LSByZWFkX3R3aXR0ZXJfY3N2KGhlcmUoInJhd19kYXRhL2NsaW1hdGVfdHd0cy5jc3YiKSkKCmBgYAoKYGBge3J9CnRzX3Bsb3QoY2xpbWF0ZV90d3RzLCBieSA9ICJob3VycyIsIGNvbG9yID0gImJsdWUiKQpgYGAKCmBgYHtyfQojIExvYWRpbmcgUmVnZXggbGlicmFyeQpsaWJyYXJ5KHFkYXBSZWdleCkKCiMgRXh0cmFjdCB0d2VldCB0ZXh0IGZyb20gY2xpbWF0ZSBkYXRhc2V0CnR3dF90eHQgPC0gY2xpbWF0ZV90d3RzJHRleHQKaGVhZCh0d3RfdHh0KQoKIyBSZW1vdmUgVVJMcyBmcm9tIHRoZSB0d2VldCB0ZXh0CnR3dF90eHRfdXJsIDwtIHJtX3R3aXR0ZXJfdXJsKHR3dF90eHQpCgojIFJlcGxhY2Ugc3BlY2lhbCBjaGFyYWN0ZXJzLCBwdW5jdHVhdGlvbiwgJiBudW1iZXJzIHdpdGggc3BhY2VzCnR3dF90eHRfY2hycyAgPC0gZ3N1YigiW15BLVphLXpdIiwiICIgLCB0d3RfdHh0X3VybCkKCiMgTG9hZGluZyB0ZXh0IG1pbmluZyBsaWJyYXJ5CmxpYnJhcnkodG0pCgojIENvbnZlcnQgdGV4dCBpbiAidHd0X2dzdWIiIGRhdGFzZXQgdG8gYSB0ZXh0IGNvcnB1cwp0d3RfY29ycHVzIDwtIHR3dF90eHRfY2hycyAlPiUgCiAgICAgICAgICAgICAgICBWZWN0b3JTb3VyY2UoKSAlPiUgCiAgICAgICAgICAgICAgICBDb3JwdXMoKSAKCiMgQ29udmVydCB0aGUgY29ycHVzIHRvIGxvd2VyY2FzZQp0d3RfY29ycHVzX2x3ciA8LSB0bV9tYXAodHd0X2NvcnB1cywgdG9sb3dlcikgCgojIFJlbW92ZSBFbmdsaXNoIHN0b3Agd29yZHMgZnJvbSB0aGUgY29ycHVzIHVzaW5nIFNNQVJUIGRpY3Rpb25hcnkgYW5kIHZpZXcgdGhlIGNvcnB1cwp0d3RfY29ycHVzX3N0cHdkIDwtIHRtX21hcCh0d3RfY29ycHVzX2x3ciwgcmVtb3ZlV29yZHMsIHN0b3B3b3Jkcygic21hcnQiKSkKaGVhZCh0d3RfY29ycHVzX3N0cHdkJGNvbnRlbnQpCgojIFJlbW92ZSBhZGRpdGlvbmFsIHNwYWNlcyBmcm9tIHRoZSBjb3JwdXMKdHd0X2NvcnB1c19zcGFjZXMgPC0gdG1fbWFwKHR3dF9jb3JwdXNfc3Rwd2QsIHN0cmlwV2hpdGVzcGFjZSkKCiMgTG9hZGluZyBsaWJyYXJ5IGZvciB0ZXh0IGFuYWx5c2lzCmxpYnJhcnkocWRhcCkKCiMgRXh0cmFjdCB0ZXJtIGZyZXF1ZW5jaWVzIGZvciB0b3AgNjAgd29yZHMgYW5kIHZpZXcgb3V0cHV0CnRlcm1mcmVxICA8LSAgZnJlcV90ZXJtcyh0d3RfY29ycHVzX3NwYWNlcywgNjApCnRlcm1mcmVxCmBgYAoKYGBge3J9CiMgQ3JlYXRlIGEgdmVjdG9yIG9mIGN1c3RvbSBzdG9wIHdvcmRzCmN1c3RvbV9zdG9wd2RzIDwtIGMoImFtcCIsICJ2ZSIsICJkb24iLCAibG8iLCAiY2xpbWF0ZSIsICJjaGFuZ2UiKQoKIyBSZW1vdmUgY3VzdG9tIHN0b3Agd29yZHMgYW5kIGNyZWF0ZSBhIHJlZmluZWQgY29ycHVzCmNvcnBfcmVmaW5lZCA8LSB0bV9tYXAodHd0X2NvcnB1c19zcGFjZXMsIHJlbW92ZVdvcmRzLCBjdXN0b21fc3RvcHdkcykgCgojIEV4dHJhY3QgdGVybSBmcmVxdWVuY2llcyBmb3IgdGhlIHRvcCAyNSB3b3Jkcwp0ZXJtZnJlcV8yNXcgPC0gZnJlcV90ZXJtcyhjb3JwX3JlZmluZWQsIDI1KQoKIyBJZGVudGlmeSB0ZXJtcyB3aXRoIG1vcmUgdGhhbiAzMCBjb3VudHMgZnJvbSB0aGUgdG9wIDI1IGxpc3QKdGVybTMwIDwtIHN1YnNldCh0ZXJtZnJlcV8yNXcsIEZSRVEgPiAzMCkKCgojIEJhcmNoYXJ0CnRlcm0zMCAlPiUgCmdncGxvdCgpICsKYWVzKHggPSByZW9yZGVyKFdPUkQsIC1GUkVRKSwgeSA9IEZSRVEpICsKCQlnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICJibHVlIikgKyAKICAgICAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKbGlicmFyeSh3b3JkY2xvdWQpCgojIENyZWF0ZSB3b3JkIGNsb3VkIHdpdGggMTAgY29sb3JzIGFuZCBtYXggMzAgd29yZHMKd29yZGNsb3VkKGNvcnBfcmVmaW5lZCwgbWF4LndvcmRzID0gMzAsIAogICAgY29sb3JzID0gYnJld2VyLnBhbCgxMCwgIkRhcmsyIiksIAogICAgc2NhbGU9Yyg0LDEpLCByYW5kb20ub3JkZXIgPSBGQUxTRSkKYGBgCgpgYGB7cn0KCiMgTG9hZCBsaWJyYXJpZXMKbGlicmFyeSh0b3BpY21vZGVscykKCgojIENyZWF0ZSBhIGRvY3VtZW50IHRlcm0gbWF0cml4IChEVE0pIGZvciAqY2xpbWF0ZSoKZHRtX2NsaW1hdGUgPC0gRG9jdW1lbnRUZXJtTWF0cml4KGNvcnBfcmVmaW5lZCkKCiMgRmluZCB0aGUgc3VtIG9mIHdvcmQgY291bnRzIGluIGVhY2ggZG9jdW1lbnQKcm93VG90YWxzIDwtIGFwcGx5KGR0bV9jbGltYXRlLCAxLCBzdW0pCgojIFNlbGVjdCByb3dzIHdpdGggYSByb3cgdG90YWwgZ3JlYXRlciB0aGFuIHplcm8KZHRtX2NsaW1hdGVfbmV3IDwtIGR0bV9jbGltYXRlW3Jvd1RvdGFscyA+IDAsIF0KCiMgQ3JlYXRlIGEgdG9waWMgbW9kZWwgd2l0aCAxMCB0b3BpY3MKdG9waWNtb2RsXzEwIDwtIExEQShkdG1fY2xpbWF0ZV9uZXcsIGsgPSAxMCkKCiMgU2VsZWN0IGFuZCB2aWV3IHRoZSB0b3AgMTAgdGVybXMgaW4gdGhlIHRvcGljIG1vZGVsCnRvcF8xMHRlcm1zIDwtIHRlcm1zKHRvcGljbW9kbF8xMCwgMTApCnRvcF8xMHRlcm1zIAoKCmBgYAoKYGBge3J9CmxpYnJhcnkoc3l1emhldCkKCiMgUGVyZm9ybSBzZW50aW1lbnQgYW5hbHlzaXMgZm9yIHR3ZWV0cyBvbiBgY2xpbWF0ZWAgCnNhLnZhbHVlIDwtIGdldF9ucmNfc2VudGltZW50KGNsaW1hdGVfdHd0cyR0ZXh0KQoKIyBWaWV3IHRoZSBzZW50aW1lbnQgc2NvcmVzCmhlYWQoc2EudmFsdWUsIDEwKQpgYGAKCmBgYHtyfQojIENhbGN1bGF0ZSBzdW0gb2Ygc2VudGltZW50IHNjb3JlcwpzY29yZSA8LSBjb2xTdW1zKHNhLnZhbHVlWyxdKQoKIyBDb252ZXJ0IHRoZSBzdW0gb2Ygc2NvcmVzIHRvIGEgZGF0YSBmcmFtZQpzY29yZV9kZiA8LSBkYXRhLmZyYW1lKHNjb3JlKQoKIyBDb252ZXJ0IHJvdyBuYW1lcyBpbnRvICdzZW50aW1lbnQnIGNvbHVtbiBhbmQgY29tYmluZSB3aXRoIHNlbnRpbWVudCBzY29yZXMKc2NvcmVfZGYyIDwtIGNiaW5kKHNlbnRpbWVudCA9IHJvdy5uYW1lcyhzY29yZV9kZiksICAKCQkJCSAgc2NvcmVfZGYsIHJvdy5uYW1lcyA9IE5VTEwpCnByaW50KHNjb3JlX2RmMikKCiMgUGxvdCB0aGUgc2VudGltZW50IHNjb3JlcwpnZ3Bsb3QoZGF0YSA9IHNjb3JlX2RmMiwgYWVzKHggPSBzZW50aW1lbnQsIHkgPSBzY29yZSwgZmlsbCA9IHNlbnRpbWVudCkpICsKICAJIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgICAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQpgYGAKCmBgYHtyIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkoaWdyYXBoKQoKIyBFeHRyYWN0IHNvdXJjZSB2ZXJ0ZXggYW5kIHRhcmdldCB2ZXJ0ZXggZnJvbSB0aGUgdHdlZXQgZGF0YSBmcmFtZQpycGx5X2RmIDwtIGNsaW1hdGVfdHd0c1ssIGMoInNjcmVlbl9uYW1lIiAsICJyZXBseV90b19zY3JlZW5fbmFtZSIgKV0KCiMgUmVtb3ZlIHJvd3Mgd2l0aCBtaXNzaW5nIHZhbHVlcwpycGx5X2RmX25ldyA8LSBycGx5X2RmW2NvbXBsZXRlLmNhc2VzKHJwbHlfZGYpLCBdCgojIENyZWF0ZSBhIG1hdHJpeApycGx5X21hdHJ4IDwtIGFzLm1hdHJpeChycGx5X2RmX25ldykKCiMgQ29udmVydCB0aGUgbWF0cml4IHRvIGEgcmVwbHkgbmV0d29yawpud19ycGx5IDwtIGdyYXBoX2Zyb21fZWRnZWxpc3QoZWwgPSBycGx5X21hdHJ4LCBkaXJlY3RlZCA9IFRSVUUpCgojIENhbGN1bGF0ZSBvdXQtZGVncmVlIHNjb3JlcyBmcm9tIHRoZSByZXR3ZWV0IG5ldHdvcmsKb3V0X2RlZ3JlZSA8LSBkZWdyZWUobndfcnBseSwgbW9kZSA9IGMoIm91dCIpKQoKIyBTb3J0IHRoZSBvdXQtZGVncmVlIHNjb3JlcyBpbiBkZWNyZWFzaW5nIG9yZGVyCm91dF9kZWdyZWVfc29ydCA8LSBzb3J0KG91dF9kZWdyZWUsIGRlY3JlYXNpbmcgPSBUUlVFKQoKIyBWaWV3IHVzZXJzIHdpdGggdGhlIHRvcCAyMCBvdXQtZGVncmVlIHNjb3JlcwpvdXRfZGVncmVlX3NvcnRbMToyMF0KYGBgCgpgYGB7cn0KIyBDb21wdXRlIHRoZSBpbi1kZWdyZWUgc2NvcmVzIGZyb20gdGhlIHJldHdlZXQgbmV0d29yawppbl9kZWdyZWUgPC0gZGVncmVlKG53X3JwbHksIG1vZGUgPSBjKCJpbiIpKQoKIyBTb3J0IHRoZSBpbi1kZWdyZWUgc2NvcmVzIGluIGRlY3JlYXNpbmcgb3JkZXIKaW5fZGVncmVlX3NvcnQgPC0gc29ydChpbl9kZWdyZWUsIGRlY3JlYXNpbmcgPSBUUlVFKQoKIyBWaWV3IHVzZXJzIHdpdGggdGhlIHRvcCAxMCBpbi1kZWdyZWUgc2NvcmVzCmluX2RlZ3JlZV9zb3J0WzE6MTBdCmBgYAoKYGBge3J9CiMgQ2FsY3VsYXRlIHRoZSBiZXR3ZWVubmVzcyBzY29yZXMgZnJvbSB0aGUgcmV0d2VldCBuZXR3b3JrCmJldHduX253IDwtIGJldHdlZW5uZXNzKG53X3JwbHksIGRpcmVjdGVkID0gVFJVRSkKCiMgU29ydCBiZXR3ZWVubmVzcyBzY29yZXMgaW4gZGVjcmVhc2luZyBvcmRlciBhbmQgcm91bmQgdGhlIHZhbHVlcwpiZXR3bl9ud19zb3J0IDwtIGJldHduX253ICU+JQogICAgICAgICAgICAgICAgICAgIHNvcnQoZGVjcmVhc2luZyA9IFRSVUUpICU+JQogICAgICAgICAgICAgICAgICAgIHJvdW5kKCkKCiMgVmlldyB1c2VycyB3aXRoIHRoZSB0b3AgMTAgYmV0d2Vlbm5lc3Mgc2NvcmVzIApiZXR3bl9ud19zb3J0WzE6MTBdCmBgYAoKYGBge3J9CiMgQ3JlYXRlIGEgdmFyaWFibGUgZm9yIG91dC1kZWdyZWUKZGVnX291dCA8LSBkZWdyZWUobndfcnBseSwgbW9kZSA9IGMoIm91dCIpKQpkZWdfb3V0CgojIEFtcGxpZnkgdGhlIG91dC1kZWdyZWUgdmFsdWVzCnZlcnRfc2l6ZSA8LSAoZGVnX291dCAqIDMpCiMgKyA1CgojdXNlcnMKdXNlcl9jb3MgPC0gdXNlcnNfZGF0YShjbGltYXRlX3R3dHMpICU+JQogICAgZmlsdGVyKGZvbGxvd2Vyc19jb3VudCA+IDEwMDAwMDApCgoKIyBDcmVhdGUgYSBjb2x1bW4gYW5kIGNhdGVnb3JpemUgZm9sbG93ZXIgY291bnRzIGFib3ZlIGFuZCBiZWxvdyAyMDAwCnVzZXJfY29zJGZvbGxvdyA8LSBpZmVsc2UodXNlcl9jb3MkZm9sbG93ZXJzX2NvdW50ID4gMTAwMDAwMCwgIjEiLCAiMCIpCgojIEFzc2lnbiB0aGUgbmV3IGNvbHVtbiBhcyB2ZXJ0ZXggYXR0cmlidXRlIHRvIHRoZSByZXR3ZWV0IG5ldHdvcmsKVihud19ycGx5KSRmb2xsb3dlcnMgPC0gdXNlcl9jb3MkZm9sbG93CnZlcnRleF9hdHRyKG53X3JwbHkpCgojIFNldCB0aGUgdmVydGV4IGNvbG9ycyBiYXNlZCBvbiBmb2xsb3dlciBjb3VudCBhbmQgY3JlYXRlIGEgcGxvdApzdWJfY29sb3IgPC0gYygibGlnaHQgYmx1ZSIsICJsaWdodCBwaW5rIikKCnBsb3QobndfcnBseSwKICAgICAjIGFzcCA9IDMwLzMwLAogICAgIHZlcnRleC5zaXplID0gZGVnX291dCwgZWRnZS5hcnJvdy5zaXplID0gMC4wMSwKICAgICB2ZXJ0ZXgubGFiZWwuY2V4ID0gMC4wMSwKICAgICB2ZXJ0ZXguY29sb3IgPSBzdWJfY29sb3JbYXMuZmFjdG9yKHZlcnRleF9hdHRyKG53X3JwbHksICJmb2xsb3dlcnMiKSldLAogICAgIHZlcnRleC5sYWJlbC5jb2xvciA9ICJibGFjayIsIHZlcnRleC5mcmFtZS5jb2xvciA9ICJsaWdodCBncmV5IikKYGBgCgpgYGB7cn0KCmxpYnJhcnkobWFwcykKCiMgRXh0cmFjdCBnZW8tY29vcmRpbmF0ZXMgZGF0YSB0byBhcHBlbmQgYXMgbmV3IGNvbHVtbnMKY2NfY29vcmQgPC0gbGF0X2xuZyhjbGltYXRlX3R3dHMpCgojIE9taXQgcm93cyB3aXRoIG1pc3NpbmcgZ2VvLWNvb3JkaW5hdGVzIGluIHRoZSBkYXRhIGZyYW1lCmNjX2dlbyA8LSBuYS5vbWl0KGNjX2Nvb3JkWyxjKCJsYXQiLCAibG5nIildKQoKIyBQbG90IGxvbmdpdHVkZSBhbmQgbGF0aXR1ZGUgdmFsdWVzIG9mIHR3ZWV0cyBvbiBVSyBtYXAKbWFwKGRhdGFiYXNlID0gIndvcmxkIiwgcmVnaW9uID0gIlVLKD8hcikiLCBmaWxsID0gVFJVRSwgY29sID0gImxpZ2h0IGdyZWVuIikKd2l0aChjY19nZW8sIHBvaW50cyhsbmcsIGxhdCwgcGNoID0gMjAsIGNleCA9IDEsIGNvbCA9ICdibHVlJykpCgojIFBsb3QgbG9uZ2l0dWRlIGFuZCBsYXRpdHVkZSB2YWx1ZXMgb2YgdHdlZXRzIG9uIHRoZSB3b3JsZCBtYXAKbWFwKGRhdGFiYXNlID0gIndvcmxkIiwgZmlsbCA9IFRSVUUsIGNvbCA9ICJsaWdodCBncmVlbiIpCndpdGgoY2NfZ2VvLCBwb2ludHMobG5nLCBsYXQsIHBjaCA9IDIwLCBjZXggPSAxLCBjb2wgPSAnYmx1ZScpKQpgYGAKCg==